package io.bdmc.modules.bss.controller;

import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import io.bdmc.common.annotation.SysLogger1;
import io.bdmc.common.utils.*;
import io.bdmc.common.utils.Constant.ModifyName;
import io.bdmc.common.validator.Assert;
import io.bdmc.core.msp2000.utils.FmsDeviceUtil;
import io.bdmc.core.snmp.SnmpData;
import io.bdmc.core.snmp.cache.ConcurrentHashMapCacheUtils;
import io.bdmc.core.udp.UdpClientSendData;
import io.bdmc.modules.bss.entity.*;
import io.bdmc.modules.bss.model.DeviceDynamicModel;
import io.bdmc.modules.bss.service.*;
import io.bdmc.modules.sys.controller.AbstractController;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.*;

/**
 * <p>
 * 设备基础信息 前端控制器
 * </p>
 *
 * @author ping
 * @since 2020-06-29
 */
// "设备基础信息", description = "/bss/device")
@RestController
@RequestMapping("/bss/device")
public class DeviceDeviceController extends AbstractController {

	@Autowired
	IDeviceDeviceService _deviceSvs;

	@Autowired
	IDeviceStatusStaticService _dssSvs;

	@Autowired
	IDeviceMeasureService _devMeasureSvs;
	@Autowired
	IDeviceFrameService _frameSvs;

	@Autowired
	IDeviceMonitorDynamicService _dmcSvs;

	@Autowired
	IFibreFibreService _fibreSvs;

	@Autowired
	IDeviceMeasureService _measureSvs;

	@Autowired
	IDeviceFibreMatchService _matchSvs;

	@Autowired
	IDeviceFibreRealtimeService _dfrSvs;

	@Autowired
	IDeviceAlarmRealtimeService _alarmRealSvs;

	@Autowired
	IDeviceMachineFecService _fecService;

	@Autowired
	IDeviceMachineDiskService _diskService;

	@Autowired
	IDeviceMachineFanService _fanService;

	@Autowired
	IDeviceMachineEdfaService _edfaService;

	@Autowired
	IDeviceMachineFecModuleService _fecModuleService;

	@Autowired
	IDeviceMachinePowerService _powerService;

	@Autowired
	IDeviceMachineRtService _rtService;

	@Autowired
	IDeviceMachineFspService _fspService;

	@Autowired
	IDeviceMachineRfaService _rfaService;

	@Autowired
	IDeviceMachineOswService _oswService;

	@Autowired
	IDeviceMachineOpmService _opmService;

	@Autowired
	IDeviceMachineOpmModuleService _opmModuleService;

	@Autowired
	IDeviceMachineFmsService _fmsService;

	@Autowired
	IDeviceMachineOsService _osService;

	@Autowired
	IDeviceMachineOsModuleService _osModuleService;

	@Autowired
	UdpClientSendData _udpClient;

	@Autowired
	FmsDeviceUtil _fmsDeviceUtil;

	@GetMapping("/list")
	// "所有设备信息", notes = "所有设备信息")
	// @RequiresPermissions("bss:device:list")
	public R list() {
		MyPage<DeviceDevice> myPage = new MyPage<>(1, 2000);
		MyPage<DeviceDevice> map = _deviceSvs.mySelectPage(myPage);
		return R.ok().putData(map.getRecords());
	}

	@GetMapping("fms")
	public R fms() {
		return R.ok().putData(_deviceSvs.listAllFms());
	}

	@RequestMapping(value = "export")
	public R export() throws IOException {
		HSSFWorkbook workbook = new HSSFWorkbook();
		HSSFSheet sheet = workbook.createSheet("设备列表");
		List<DeviceDevice> list = _deviceSvs.list();
		String dateString = DateUtils.formatLocalDateTime(LocalDateTime.now(), DateUtils.Pay_DATE_TIME_PATTERN);
		String fileName = "设备列表" + dateString + ".xls";// 设置要导出的文件的名字

		Map<String, CellStyle> styles = ExcelImport.createStyles(workbook);

		// 新增数据行，并且设置单元格数据
		int rowNum = 0;
		String[] headers = { "序号", "设备名称", "设备型号", "出厂序列号", "设备mac地址", "设备IP", "创建时间", "创建人" };

		rowNum = ExcelImport.initialize(rowNum, "设备信息报表", headers, workbook, sheet, styles);

		// 在表中存放查询到的数据放入对应的列
		int dataIndex = 1;
		for (DeviceDevice dd : list) {
			HSSFRow row1 = sheet.createRow(rowNum++);
			row1.createCell(0).setCellValue(dataIndex);
			row1.createCell(1).setCellValue(dd.getDeviceName());
			row1.createCell(2).setCellValue(ExcelImport.convertNullString(dd.getDeviceModel()));
			row1.createCell(3).setCellValue(ExcelImport.convertNullString(dd.getDeviceSn()));
			row1.createCell(4).setCellValue(ExcelImport.convertNullString(dd.getDeviceMac()));
			row1.createCell(5).setCellValue(ExcelImport.convertNullString(dd.getIpaddr()));
			row1.createCell(6).setCellValue(ExcelImport.convertNullString(dd.getCreateTime()));
			row1.createCell(7).setCellValue(ExcelImport.convertNullString(dd.getCreateBy()));
			dataIndex++;
		}
		try {
			File path = new File(Constant.EXPORTPATH);
			if (!path.exists()) {
				path.mkdir();
			}
			File f = new File(path.getAbsolutePath() + "/excel/", fileName);
			if (!f.getParentFile().exists()) {
				f.getParentFile().mkdir();
			}
			FileOutputStream fileOutputStream = new FileOutputStream(f);// 指定路径与名字和格式
			workbook.write(fileOutputStream);// 将数据写出去
			fileOutputStream.close();// 关闭输出流
			return R.ok().putData("/excel/" + fileName);
		} catch (Exception e) {
			e.printStackTrace();
			return R.error(-1, e.getMessage());
		}
	}

	@GetMapping("/info")
	// "查询单个设备或单盘", notes = "查询单个设备或单盘")
	public R info(int deviceId) {
		if (deviceId <= 0) {
			return R.error(-1, "参数错误");
		}
		DeviceDevice device = _deviceSvs.getById(deviceId);
		return R.ok().putData(device);
	}

	@PostMapping("/edit")
	// "修改设备类型", notes = "修改设备类型")
	public R edit(@RequestBody DeviceDevice device) {
		LambdaUpdateWrapper<DeviceDevice> w1 = new LambdaUpdateWrapper<DeviceDevice>()
				.eq(DeviceDevice::getDeviceId, device.getDeviceId())
				.set(DeviceDevice::getDeviceType, device.getDeviceType())
				.set(DeviceDevice::getDeviceName, device.getDeviceName());
		Boolean result = _deviceSvs.update(w1);
		return R.trueOrFalse(result);
	}

	/**
	 * 查询设备下面的子设备
	 * 
	 * @param deviceId
	 * @return
	 */
	@GetMapping("/disks")
	// "查询设备下面的子设备", notes = "查询设备下面的子设备")
	public R disks(int deviceId) {
		if (deviceId <= 0) {
			return R.error(-1, "参数错误");
		}
		List<DeviceDevice> device = _deviceSvs.list(new QueryWrapper<DeviceDevice>().eq("parent_id", deviceId));
		return R.ok().putData(device);
	}

	@SysLogger1(value = "新增设备基础信息", entityType = DeviceDevice.class, operationType = ModifyName.ADD)
	@PostMapping("/save")
	// "新增DeviceDevice", notes = "新增设备基础信息")
	@RequiresPermissions("bss:device:save")
	public R save(@RequestBody DeviceDevice device) {
		R error = checkDeviceValid(device);
		if (error != null)
			return error;
		if (device.getDeviceType().equals(Constant.MSP2000)) {
			device.setDeviceSn(CommonUtil.getOrderIdByUUId());
		}
		device.setDeviceId(null);
		device.setCreateBy(getUser().getUsername());
		device.setCreateTime(LocalDateTime.now());
		device.setDeptId(getDeptId().intValue());
		Boolean b = device.insert();
		return R.trueOrFalse(b);
	}

	private R checkDeviceValid(DeviceDevice device) {
		if (device.getDeviceDigest().equals(Constant.MSP2000) || device.getDeviceDigest().equals(Constant.IFMS1000)) {
			device.setDeviceType(device.getDeviceDigest());
		}
		device.setDeviceModel(device.getDeviceType());
		DeviceFrame df = _frameSvs.getById(device.getFrameId());
		int totalLayerRow = df.getLayer();
		if (device.getLayerRow() > totalLayerRow || device.getLayerRow() <= 0) {
			return R.error(-1, "设备所在层数填写不正确");
		}
		QueryWrapper<DeviceDevice> w1 = new QueryWrapper<DeviceDevice>().eq("frame_id", device.getFrameId())
				.eq("layer_row", device.getLayerRow()).ne("device_id", device.getDeviceId()).last("LIMIT 1");
		if (_deviceSvs.getOne(w1) != null) {
			return R.error(-1, "该层已存在一个设备，请更换其他的层");
		}
		return null;
	}

	@PostMapping("/save_disk")
	// "新增1U设备", notes = "新增1U设备")
	@RequiresPermissions("bss:device:save")
	public R saveDisk(@RequestBody DeviceDevice device) {
		DeviceDevice parentDevice = _deviceSvs.getById(device.getParentId());
		device.setDeviceModel(device.getDeviceType());
		device.setCreateBy(getUser().getUsername());
		device.setCreateTime(LocalDateTime.now());
		device.setDeptId(parentDevice.getDeptId());
		Boolean b = device.insert();
		return R.trueOrFalse(b);
	}

	@SysLogger1(value = "修改设备基础信息", entityType = DeviceDevice.class, operationType = ModifyName.UPDATE)
	@PostMapping("/update")
	// "修改DeviceDevice", notes = "修改设备基础信息")
	@RequiresPermissions("bss:device:update")
	public R update(@RequestBody DeviceDevice device) {
		// 修改fsp 绑定关系时不用判断设备层数信息
		if (device.getDeviceType().equals(Constant.MSP2000)) {
			R error = checkDeviceValid(device);
			if (error != null)
				return error;
		}

		Boolean b = device.updateById();
		return R.trueOrFalse(b);
	}

	@SysLogger1(value = "删除设备基础信息", entityType = DeviceDevice.class, operationType = ModifyName.DELETE)
	@PostMapping("/delete")
	// "删除DeviceDevice", notes = "删除设备基础信息")
	@RequiresPermissions("bss:device:delete")
	public R delete(@RequestBody long deviceId) {
		if (deviceId > 0) {
			DeviceDevice dd = _deviceSvs.getById(deviceId);
			if (dd != null && dd.getDeviceType().equals(Constant.MSP2000)) {
				// 删除子设备先
				List<DeviceDevice> deviceList = _deviceSvs
						.list(new QueryWrapper<DeviceDevice>().eq("parent_id", dd.getDeviceId()));
				for (DeviceDevice deviceDevice : deviceList) {
					_matchSvs.remove(new QueryWrapper<DeviceFibreMatch>().eq("device_id", deviceDevice.getDeviceId()));
					_deviceSvs.removeById(deviceDevice.getDeviceId());
				}
			}
			_matchSvs.remove(new QueryWrapper<DeviceFibreMatch>().eq("device_id", deviceId));
			_deviceSvs.removeById(deviceId);
		}
		return R.ok();
	}

	@GetMapping("/ztree")
	// "ztree", notes = "ztree")
	public R ztree() {
		List<HashMap<String, Object>> map = _deviceSvs.ztreeDeviceList(getDeptId());
		return R.ok().putData(map);
	}

	@GetMapping("linkTree")
	// "linkTree", notes = "linkTree")
	public R linkTree() {
		List<Map<String, Object>> map = _deviceSvs.linkTree(getDeptId());
		return R.ok().putData(map);
	}

	@GetMapping("/param")
	// "高级参数", notes = "高级参数")
	public R param(int deviceId) {
		Assert.intIsLessEqZero(deviceId, "参数错误");
		DeviceMonitorDynamic dy = _dmcSvs
				.getOne(new QueryWrapper<DeviceMonitorDynamic>().eq("device_id", deviceId).last("LIMIT 1"));
		if (dy == null) {
			return R.error(-1, "未找到指定设备");
		}
		String[] endPositionArr = dy.getEndPosition().split(",");
		String[] refIndexArr = dy.getRefIndex().split(",");
		String[] resolutionArr = dy.getResolution().split(",");
		String[] statusArr = dy.getStatus().split(",");
		String[] actionArr = dy.getAction().split(",");
		String[] pulseWidthArr = dy.getPulseWidth().split(",");
		String[] portActiveArr = dy.getPortActive().split(",");
		String[] timeArr = dy.getTime().split(",");
		String[] progressStatusArr = dy.getProgressStatus().split(",");
		String[] flctArr = dy.getFiberLengthChangeThreshold().split(",");
		String[] etelhtArr = dy.getEndToEndLossHighThreshold().split(",");
		String[] etelmtArr = dy.getEndToEndLossMiddleThreshold().split(",");
		String[] etelltArr = dy.getEndToEndLossLowThreshold().split(",");
		String[] olctArr = dy.getOldLossCriticalThreshold().split(",");
		String[] olmaxtArr = dy.getOldLossMajorThreshold().split(",");
		String[] olmintArr = dy.getOldLossMinorThreshold().split(",");
		String[] nlctArr = dy.getNewLossCriticalThreshold().split(",");
		String[] nlmaxtArr = dy.getNewLossMajorThreshold().split(",");
		String[] nlmintArr = dy.getNewLossMinorThreshold().split(",");
		String[] epctArr = dy.getEventPositionChangeThreshold().split(",");
		String[] accArr = dy.getAttenuationCoefficientChange().split(",");
		String[] tlosArr = dy.getTlos().split(",");
		String[] trefArr = dy.getTref().split(",");
		String[] nssecArr = dy.getNumberSorStoredEachChannel().split(",");
		String[] fltctArr = dy.getFiberLengthTrapComparisonTimes().split(",");
		String[] tsArr = dy.getTrapShielding().split(",");

		List<HashMap<String, String>> list = new ArrayList<HashMap<String, String>>();
		for (int i = 0; i < flctArr.length; i++) {
			HashMap<String, String> map = new HashMap<String, String>(8);
			map.put("ipaddr", dy.getDevIpAddr());
			map.put("channel", String.valueOf(i + 1));
			map.put("endPosition", endPositionArr[i]);
			map.put("refIndex", refIndexArr[i]);
			map.put("resolution", resolutionArr[i]);
			map.put("status", statusArr[i]);
			map.put("action", actionArr[i]);
			map.put("pulseWidth", pulseWidthArr[i]);
			map.put("portActive", portActiveArr[i]);
			map.put("time", timeArr[i]);
			map.put("progressStatus", progressStatusArr[i]);
			map.put("fiberLengthChangeThreshold", flctArr[i]);
			map.put("endToEndLossHighThreshold", etelhtArr[i]);
			map.put("endToEndLossMiddleThreshold", etelmtArr[i]);
			map.put("endToEndLossLowThreshold", etelltArr[i]);
			map.put("oldLossCriticalThreshold", olctArr[i]);
			map.put("oldLossMajorThreshold", olmaxtArr[i]);
			map.put("oldLossMinorThreshold", olmintArr[i]);
			map.put("newLossCriticalThreshold", nlctArr[i]);
			map.put("newLossMajorThreshold", nlmaxtArr[i]);
			map.put("newLossMinorThreshold", nlmintArr[i]);
			map.put("eventPositionChangeThreshold", epctArr[i]);
			map.put("attenuationCoefficientChange", accArr[i]);
			map.put("tlos", tlosArr[i]);
			map.put("tref", trefArr[i]);
			map.put("numberSorStoredEachChannel", nssecArr[i]);
			map.put("fiberLengthTrapComparisonTimes", fltctArr[i]);
			map.put("trapShielding", tsArr[i]);
			list.add(i, map);
		}

		return R.ok().putData(list);
	}

	@PostMapping("/preset")
	// "设置高级参数", notes = "设置高级参数")
	public R setParam(@RequestBody JSONObject json) {
		String ipAddr = json.getString("ipAddr");
		String channel = json.getString("channel");
		String property = json.getString("property");
		String valueObject = json.getString("valueObject");
		boolean b = false;
		final DeviceDevice device = _deviceSvs.getDeviceByIp(ipAddr);
		if (property.equals("portActive") || property.equals("time")) {
			b = SnmpData.setSnmpValue(ipAddr, channel, property, Integer.parseInt(valueObject), device.getWriteCode());
		} else {
			b = SnmpData.setSnmpValue(ipAddr, channel, property, valueObject, device.getWriteCode());
		}
		return R.ok().putData(b);
	}

	@GetMapping("/status")
	// "获取设备状态信息", notes = "获取设备状态信息")
	public R status(int deviceId) {
		Assert.intIsLessEqZero(deviceId, "参数错误");
		DeviceDevice dev = _deviceSvs.getById(deviceId);

		DeviceStatusStatic dss = (DeviceStatusStatic) ConcurrentHashMapCacheUtils
				.getCache(Constant.DeviceStatusStaticPrefix + dev.getIpaddr());
		if (dss == null || dss.getDevIpAddr() == null) {
			return R.error(-1, "设备IP错误，未能获取数据");
		}

		// 需要更新缓存中的静态statusStaticMap
		DeviceMonitorDynamic dmc = (DeviceMonitorDynamic) ConcurrentHashMapCacheUtils
				.getCache(Constant.DeviceMonitorDynamicPrefix + ":" + dss.getDevIpAddr());
		if (dmc != null) {
			List<DeviceFibreMatch> deviceFibreMatchList = _matchSvs
					.list(new QueryWrapper<DeviceFibreMatch>().eq("device_id", deviceId));
			List<DeviceDynamicModel> list = new ArrayList<DeviceDynamicModel>();
			String[] statusArr = dmc.getStatus().split(",");
			String[] portActiveArr = dmc.getPortActive().split(",");
			String[] endPositionArr = dmc.getEndPosition().split(",");
			String[] pulseWidthArr = dmc.getPulseWidth().split(",");
			String[] timeArr = dmc.getTime().split(",");
			String[] resolutionArr = dmc.getResolution().split(",");
			String[] refIndexArr = dmc.getRefIndex().split(",");
			String[] numberArr = dmc.getNumber().split(",");
			for (int i = 0; i < statusArr.length; i++) {
				int channel = i + 1;
				DeviceDynamicModel ddm = new DeviceDynamicModel();
				ddm.setStatus(Integer.parseInt(statusArr[i]));
				ddm.setPortActive(Integer.parseInt(portActiveArr[i]));
				ddm.setChannel(channel);
				ddm.setEndPosition(endPositionArr[i]);
				ddm.setPulseWidth(pulseWidthArr[i]);
				ddm.setRefIndex(refIndexArr[i]);
				ddm.setTime(timeArr[i]);
				ddm.setResolution(resolutionArr[i]);
				ddm.setNumber(numberArr[i]);
				Optional<DeviceFibreMatch> ff = deviceFibreMatchList.stream()
						.filter(r -> r.getChannel().equals(channel)).findFirst();
				if (ff.isPresent()) {
					ddm.setFibreName(ff.get().getFibreName() + "#" + ff.get().getFibreCoreIndex());
					ddm.setAlarmValue(ff.get().getAlarmValue());
					ddm.setNormalValue(ff.get().getNormalValue());
					ddm.setFibreId(ff.get().getFibreId());
					ddm.setNormalPadControl(ff.get().getNormalPadControl());
					ddm.setDeviceFibreId(ff.get().getDeviceFibreId());
					// 缓存中拿实时信息
					String data = (String) ConcurrentHashMapCacheUtils
							.getCache(Constant.DeviceChannelRealtimePrefix + dev.getIpaddr() + ":" + channel);
					if (!StringUtils.isEmpty(data)) {
						ddm.setFibreLength(data.split(",")[0]);
						ddm.setFibreLoss(data.split(",")[1]);
					} else {// 从数据库拿实时信息
						QueryWrapper<DeviceFibreRealtime> w1 = new QueryWrapper<DeviceFibreRealtime>();
						w1.eq("ip_addr", dev.getIpaddr()).eq("channel", channel).last(" LIMIT 1");
						DeviceFibreRealtime dfr = _dfrSvs.getOne(w1);
						if (dfr != null) {
							ddm.setFibreLength(dfr.getFibreLength());
							ddm.setFibreLoss(dfr.getFibreLoss());
						}
					}
					QueryWrapper<DeviceAlarmRealtime> w1 = new QueryWrapper<DeviceAlarmRealtime>();
					w1.eq("channel", channel).eq("device_id", ff.get().getDeviceId())
							.eq("alarm_type_code", Constant.ALARM_Distance).last("LIMIT 1");
					DeviceAlarmRealtime alarm = _alarmRealSvs.getOne(w1);
					if (alarm != null) {
						ddm.setAlarmMsg(alarm.getAlarmMsg());
					}
				}
				list.add(ddm);
			}
			HashMap<String, Object> map = new HashMap<>(2);
			map.put("deviceStatus", dss);
			map.put("channelStatus", list);
			return R.ok().putData(map);
		}
		return R.ok();
	}

	@PostMapping("/setting/network")
	// "设置网络参数", notes = "设置网络参数")
	public R settingNetwork(@RequestBody JSONObject json) {
		String ipAddr = json.getString("ipAddr");
		String devIpAddr = json.getString("devIpAddr");
		String devGateway = json.getString("devGateway");
		String devNetMask = json.getString("devNetMask");
		final DeviceDevice device = _deviceSvs.getDeviceByIp(ipAddr);
		SnmpData.setSnmpValue(ipAddr, "0", "devIpAddr", devIpAddr, device.getWriteCode());
		SnmpData.setSnmpValue(ipAddr, "0", "devGateway", devGateway, device.getWriteCode());
		SnmpData.setSnmpValue(ipAddr, "0", "devNetMask", devNetMask, device.getWriteCode());
		SnmpData.setSnmpValue(ipAddr, "0", "saveCurrentConfiguration", 1, device.getWriteCode());
		device.setIpaddr(devIpAddr);
		boolean b = device.updateById();
		return R.trueOrFalse(b);
	}

	@PostMapping("/setting/trap")
	// "设置trap地址", notes = "设置trap地址")
	public R settingTrap(@RequestBody JSONObject json) {
		String ipAddr = json.getString("ipAddr");
		String[] trapTargetIpAddrArr = json.getString("trapTargetIpAddr").split(",");
		boolean b = false;
		final DeviceDevice device = _deviceSvs.getDeviceByIp(ipAddr);
		for (int i = 0; i < trapTargetIpAddrArr.length; i++) {
			b = SnmpData.setSnmpValue(ipAddr, i + 1 + "", "trapTargetIpAddr", trapTargetIpAddrArr[i],
					device.getWriteCode());
		}
		return R.trueOrFalse(b);
	}

	@PostMapping("/setting/temperature")
	// "设置温度", notes = "设置温度")
	public R settingTemperature(@RequestBody JSONObject json) {
		String ipAddr = json.getString("ipAddr");
		String temperatureHighThreshold = json.getString("temperatureHighThreshold");
		String temperatureLowThreshold = json.getString("temperatureLowThreshold");
		int TemperatureControlMode = json.getIntValue("temperatureControlMode");
		final DeviceDevice device = _deviceSvs.getDeviceByIp(ipAddr);
		boolean b = SnmpData.setSnmpValue(ipAddr, "0", "temperatureControlMode", TemperatureControlMode,
				device.getWriteCode());
		b = SnmpData.setSnmpValue(ipAddr, "0", "temperatureHighThreshold", temperatureHighThreshold,
				device.getWriteCode());
		b = SnmpData.setSnmpValue(ipAddr, "0", "temperatureLowThreshold", temperatureLowThreshold,
				device.getWriteCode());
		return R.trueOrFalse(b);
	}

	@PostMapping("/setting/switch")
	// "设置串口值", notes = "设置串口值")
	public R reboot(@RequestBody JSONObject json) {
		String ipAddr = json.getString("ipAddr");
		int adg707Switch = json.getIntValue("adg707Switch");
		final DeviceDevice device = _deviceSvs.getDeviceByIp(ipAddr);
		boolean b = SnmpData.setSnmpValue(ipAddr, "0", "adg707Switch", adg707Switch, device.getWriteCode());
		return R.trueOrFalse(b);
	}

	@PostMapping("/setting/reboot")
	// "重启模块", notes = "重启模块")
	public R moduleReboot(@RequestBody JSONObject json) {
		String ipAddr = json.getString("ipAddr");
		final DeviceDevice device = _deviceSvs.getDeviceByIp(ipAddr);
		int type = json.getIntValue("type");
		boolean b = false;
		switch (type) {
			case 0:
				b = SnmpData.setSnmpValue(ipAddr, "0", "reboot", 1, device.getWriteCode());
				break;
			case 1:
				b = SnmpData.setSnmpValue(ipAddr, "0", "resetModular1", 1, device.getWriteCode());
				break;
			case 2:
				b = SnmpData.setSnmpValue(ipAddr, "0", "resetModular2", 1, device.getWriteCode());
				break;
			default:
				break;
		}

		return R.trueOrFalse(b);
	}

	@PostMapping("/setting/uploadbin")
	// "上传文件到ftp", notes = "上传文件到ftp")
	public R uploadFileToFtp(@RequestBody JSONObject json) {
		String ipAddr = json.getString("ipAddr");
		int upgDstSlot = json.getIntValue("upgDstSlot");
		String filePath = json.getString("filePath");
		final DeviceDevice device = _deviceSvs.getDeviceByIp(ipAddr);
		boolean b = FTPUtils.uploadFile("files" + filePath, "/nand/module/firmware/", ipAddr, "ifms", "ifms");
		if (b) {
			b = SnmpData.setSnmpValue(ipAddr, "0", "upgDstSlot", upgDstSlot, device.getWriteCode());
			b = SnmpData.setSnmpValue(ipAddr, "0", "upgAction", 1, device.getWriteCode());
		}
		return R.trueOrFalse(b);
	}

	@GetMapping("detail")
	public R getDeviceDetail(DeviceDevice device) throws Exception {
		DeviceDevice dd = null;
		if (device.getDeviceId() != null && device.getDeviceId() > 0) {
			dd = _deviceSvs.getById(device.getDeviceId());
		} else if (StringUtils.isNotEmpty(device.getDeviceSn())) {
			dd = _deviceSvs.getDeviceBySn(device.getDeviceSn());
		}
		if (dd == null) {
			return R.error(-1, "设备不存在或已移除");
		}
		HashMap<String, Object> map = new HashMap<>();
		map.put("device", dd);
		if (dd.getParentId() > 0) {
			DeviceDevice parentDevice = _deviceSvs.getDeviceDetail(dd.getParentId());
			map.put("parent", parentDevice);
		}
		if (dd.getDeviceDigest().equals(Constant.DTS)) {
			return R.ok().putData(map);
		} else if (dd.getDeviceDigest().equals(Constant.MSP2000)) {
			DeviceMachineDisk disk = _diskService
					.getOne(new QueryWrapper<DeviceMachineDisk>().eq("disk_sn", dd.getDeviceSn()).last("limit 1"));
			map.put("disk", disk);
			if (disk == null) {
				if (!dd.isFMS() && !dd.isOTDR())
					return R.ok().putData(map);
			}
		}

		if (dd.getDeviceType().contains("FEC")) {
			DeviceMachineFec fecData = _fecService.selectLastFecData(dd.getDeviceSn());
			if (fecData != null) {
				fecData.setFecModuleList(_fecModuleService.list(
						new QueryWrapper<DeviceMachineFecModule>().eq("machine_fec_id", fecData.getMachineFecId())));
			}
			map.put("fec", fecData);
		} else if (dd.getDeviceType().equals("FAN")) {
			List<DeviceMachineFan> fan = _fanService.selectLastFanData(dd.getDeviceSn());
			map.put("fan", fan);
			List<DeviceMachinePower> powerList = _powerService.selectLastPowerData(dd.getDeviceSn());
			map.put("powerList", powerList);
		} else if (dd.getDeviceType().equals("EDFA") || dd.getDeviceType().equals("BA")
				|| dd.getDeviceType().equals("PA")) {
			DeviceMachineEdfa edfa = _edfaService.selectLastEdfaData(dd.getDeviceSn());
			map.put("edfa", edfa);
		} else if (dd.getDeviceType().equals("RT") || dd.getDeviceType().equals("RTBA")) {
			DeviceMachineRt rt = _rtService.selectLastRtData(dd.getDeviceSn());
			map.put("rt", rt);
		} else if (dd.getDeviceType().equals("RFA")) {
			DeviceMachineRfa rfa = _rfaService.selectLastRfaData(dd.getDeviceSn());
			map.put("rfa", rfa);
		} else if (dd.getDeviceType().equals("FSP6") || dd.getDeviceType().equals("FSP8")) {
			DeviceMachineFsp fsp = _fspService.selectLastFspData(dd.getDeviceSn());
			map.put("fsp", fsp);
		} else if (dd.getDeviceType().equals("OSW")) {
			DeviceMachineOsw osw = _oswService.selectLastOswData(dd.getDeviceSn());
			map.put("osw", osw);
		} else if (dd.getDeviceType().equals("OPM")) {
			DeviceMachineOpm opm = _opmService.selectLastOpmData(dd.getDeviceSn());
			if (opm != null) {
				opm.setOpmModuleList(_opmModuleService
						.list(new QueryWrapper<DeviceMachineOpmModule>().eq("machine_opm_id", opm.getMachineOpmId())));
			}
			map.put("opm", opm);
		} else if (dd.isFMS() || dd.isOTDR()) {
			DeviceMachineFms fms = _fmsService.selectLastFmsData(dd.getDeviceSn());
			String str = dd.isOTDR() ? Constant.FMSM : Constant.FMS;
			if (fms == null) {
				DeviceDevice parent = _deviceSvs.getById(dd.getParentId());
				String ip = dd.isOTDR() ? dd.getIpaddr() : parent.getIpaddr();
				int port = dd.isOTDR() ? dd.getDevicePort() : parent.getDevicePort();
				fms = _fmsDeviceUtil.getFmsData(dd.getLayerRow(), ip, port, str);
				if (fms != null) {
					String realtimeState = _fmsDeviceUtil.getFmsStatus(dd.getLayerRow(), ip, port, str);
					String refIndex = _fmsDeviceUtil.readFMSRefIndex(dd.getLayerRow(), ip, port, str);
					String time = _fmsDeviceUtil.readFMSMeasureTime(dd.getLayerRow(), ip, port, str);
					fms.setState(realtimeState);
					fms.setRefIndex(refIndex);
					fms.setMeasureTime(Integer.parseInt(time));
					fms.setDeviceId(dd.getDeviceId());
					fms.setDiskSn(dd.getDeviceSn());
					fms.insert();
					map.put("fms", fms);
				}
			} else {
				map.put("fms", fms);
			}
		} else if (dd.getDeviceType().equals("OS")) {
			DeviceMachineOs os = _osService.selectLastOsData(dd.getDeviceSn());
			if (os != null) {
				os.setOsModuleList(_osModuleService
						.list(new QueryWrapper<DeviceMachineOsModule>().eq("machine_os_id", os.getMachineOsId())));
			}
			map.put("os", os);
		}

		return R.ok().putData(map);
	}
}